package link.chengguo.orangemall.modules.wechat.rest.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import link.chengguo.orangemall.api.ApiResult;
import link.chengguo.orangemall.api.OrangeException;
import link.chengguo.orangemall.common.bean.LocalUser;
import link.chengguo.orangemall.common.util.JwtToken;
import link.chengguo.orangemall.enums.AppFromEnum;
import link.chengguo.orangemall.modules.services.AuthService;
import link.chengguo.orangemall.modules.user.domain.OrangeUser;
import link.chengguo.orangemall.modules.user.service.OrangeUserService;
import link.chengguo.orangemall.modules.wechat.rest.param.BindPhoneParam;
import link.chengguo.orangemall.modules.wechat.rest.param.WxPhoneParam;
import link.chengguo.orangemall.utils.RedisUtils;
import link.chengguo.orangemall.utils.ShopKeyUtils;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(value = "微信其他", tags = "微信:微信其他", description = "微信其他")
public class WxMaUserController {

    private final WxMaService wxMaService;
    private final OrangeUserService userService;
    private final AuthService authService;
    private final RedisUtils redisUtils;

    @Value("${single.login:false}")
    private Boolean singleLogin;


    @PostMapping("/binding")
    @ApiOperation(value = "公众号绑定手机号", notes = "公众号绑定手机号")
    public ApiResult<String> verify(@Validated @RequestBody BindPhoneParam param) {
        Object codeObj = redisUtils.get("code_" + param.getPhone());
        if(codeObj == null){
            return ApiResult.fail("请先获取验证码");
        }
        String code = codeObj.toString();

        if (!StrUtil.equals(code, param.getCaptcha())) {
            return ApiResult.fail("验证码错误");
        }
        OrangeUser user = LocalUser.getUser();
        if(StrUtil.isNotBlank(user.getPhone())){
            return ApiResult.fail("您的账号已经绑定过手机号码");
        }

        user.setPhone(param.getPhone());
        userService.updateById(user);

        return ApiResult.ok("绑定成功");

    }


    @PostMapping("/wxapp/binding")
    @ApiOperation(value = "小程序绑定手机号", notes = "小程序绑定手机号")
    public ApiResult<Map<String,Object>> phone(@Validated @RequestBody WxPhoneParam param, HttpServletRequest request) {
        OrangeUser user = userService.getOne(new QueryWrapper<OrangeUser>().eq("username",param.getOpenId()));
        if(user == null){
            user = (OrangeUser) redisUtils.get(param.getOpenId());
        }
//        if(StrUtil.isNotBlank(user.getPhone())){
//            throw new OrangeException("您的账号已经绑定过手机号码");
//        }

        //读取redis配置
        String appId = redisUtils.getY(ShopKeyUtils.getWxAppAppId());
        String secret = redisUtils.getY(ShopKeyUtils.getWxAppSecret());
        if (StrUtil.isBlank(appId) || StrUtil.isBlank(secret)) {
            throw new OrangeException("请先配置小程序");
        }
        WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
        wxMaConfig.setAppid(appId);
        wxMaConfig.setSecret(secret);
        wxMaService.setWxMaConfig(wxMaConfig);
        String phone = "";
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService()
                    .getSessionInfo(param.getCode());

            // 解密
            WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService()
                    .getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());

            phone = phoneNoInfo.getPhoneNumber();
            OrangeUser appUser = userService.getOne(new QueryWrapper<OrangeUser>().eq("phone",phone));
            if(appUser != null){
                appUser.setUsername(user.getUsername())
                        .setLastIp(user.getLastIp())
                        .setWxProfile(user.getWxProfile());
                user = appUser;
            }
            user.setPhone(phone);
            userService.saveOrUpdate(user);
            userService.setSpread(param.getSpread(), user.getUid());
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new OrangeException("绑定失败");
        }
        String token = JwtToken.makeToken(user.getUid());
        String expiresTimeStr = JwtToken.getExpireTime(token);

        // 保存在线信息
        authService.save(user, token, request);
        // 返回 token
        Map<String, Object> map = new HashMap<String, Object>(2) {{
            put("token", token);
            put("expires_time", expiresTimeStr);
        }};

        userService.setSpread(param.getSpread(), user.getUid());

        if (singleLogin) {
            //踢掉之前已经登录的token
            authService.checkLoginOnUser(user.getUsername(), token);
        }

        return ApiResult.ok(map).setMsg("绑定成功");
    }



}
